package vip.liux.front.domain.models.chat;

import jakarta.annotation.Nonnull;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import vip.liux.core.exception.BusinessException;
import vip.liux.front.domain.enums.ChatMessageSide;
import vip.liux.front.infrastructure.tenant.TenantContext;

import java.time.Instant;
import java.util.List;

@Component
public class MessagingManager {
    private final IChatMessageRepository messageRepository;
    private final IChatUserMessageRepository userMessageRepository;
    private final IChatUserLookupService chatUserLookupService;
    private final IChatConversationRepository conversationRepository;

    public static final String Volo_Abp_Chat_010001 = "Message should not be empty!";
    public static final String Volo_Abp_Chat_010002 = "Receiver user not found!";
    public static final String Volo_Abp_Chat_010003 = "Other user not found!";

    public MessagingManager(IChatMessageRepository messageRepository, IChatUserMessageRepository userMessageRepository, IChatUserLookupService chatUserLookupService, IChatConversationRepository conversationRepository) {
        this.messageRepository = messageRepository;
        this.userMessageRepository = userMessageRepository;
        this.chatUserLookupService = chatUserLookupService;
        this.conversationRepository = conversationRepository;
    }

    /**
     * Create new message
     *
     * @param sendId      send id
     * @param receiverId  receiver id
     * @param messageText message text
     */
    public void createNewMessage(Long sendId, Long receiverId, @Nonnull String messageText) {
        Assert.notNull(messageText, "messageText cannot be null");

        // 查询接收者用户
        ChatUser receiverUser = chatUserLookupService.findUserById(receiverId);
        if (receiverUser == null) {
            throw new BusinessException(Volo_Abp_Chat_010001);
        }

        // 保存消息
        ChatMessage message = messageRepository.save(new ChatMessage(messageText, TenantContext.getCurrentTenant()));

        // 保存接收者用户消息记录
        userMessageRepository.save(new ChatUserMessage(
                sendId,
                message.getId(),
                ChatMessageSide.Sender,
                receiverId,
                TenantContext.getCurrentTenant()
        ));

        // 保存发送者用户消息记录
        userMessageRepository.save(new ChatUserMessage(
                receiverId,
                message.getId(),
                ChatMessageSide.Receiver,
                sendId,
                TenantContext.getCurrentTenant()
        ));
        // 创建或更新会话信息
        createOrUpdateConversationWithNewMessage(sendId, receiverId, messageText);
    }

    /**
     * Create or update conversation with new message
     *
     * @param sendId      send id
     * @param receiverId  receiver id
     * @param messageText message text
     */
    private void createOrUpdateConversationWithNewMessage(Long sendId, Long receiverId, String messageText) {
        Instant now = Instant.now();

        // 查询最新的接收者/发送者的会话信息
        ConversationPair conversationPair = conversationRepository.findPair(sendId, receiverId);
        if (conversationPair == null) { // 如果没有会话信息, 则创建新的会话信息
            // 保存发送者未读消息
            ChatConversation senderConversation = new ChatConversation(
                    sendId,
                    receiverId,
                    TenantContext.getCurrentTenant()
            );
            senderConversation.setLastMessageSide(ChatMessageSide.Sender.ordinal());
            senderConversation.setLastMessage(messageText);
            senderConversation.setLastMessageDate(now);

            // 保存接收者未读消息
            ChatConversation receiverConversation = new ChatConversation(
                    receiverId,
                    sendId,
                    TenantContext.getCurrentTenant()
            );
            receiverConversation.setLastMessageSide(ChatMessageSide.Receiver.ordinal());
            receiverConversation.setLastMessage(messageText);
            receiverConversation.setLastMessageDate(now);

            receiverConversation.addUnreadMessage();

            conversationRepository.save(senderConversation);
            conversationRepository.save(receiverConversation);
            return;
        }

        // 更新会话信息
        conversationPair.senderConversation().setLastMessage(messageText, now, ChatMessageSide.Sender);
        conversationPair.targetConversation().setLastMessage(messageText, now, ChatMessageSide.Receiver);

        conversationRepository.save(conversationPair.senderConversation());
        conversationRepository.save(conversationPair.targetConversation());
    }


    /**
     * Read messages
     *
     * @param targetUserId   target user id
     * @param skipCount      skip count
     * @param maxResultCount max result count
     * @return message list
     */
    public List<MessageWithDetails> readMessages(Long userId, Long targetUserId, int skipCount, int maxResultCount) {
        Instant now = Instant.now();

        // 查询用户聊天消息
        List<MessageWithDetails> messages = userMessageRepository.getMessages(userId, targetUserId, skipCount, maxResultCount);

        for (MessageWithDetails message : messages) { // 标记消息为已读
            message.userMessage().markAsRead(now);
            userMessageRepository.save(message.userMessage());

            message.message().markAsAllRead(now);
            messageRepository.save(message.message());
        }

        // 查询会话信息, 并重置未读消息数量
        ConversationPair conversationPair = conversationRepository.findPair(userId, targetUserId);
        conversationPair.senderConversation().resetUnreadMessageCount();

        conversationRepository.save(conversationPair.senderConversation());
        conversationRepository.save(conversationPair.targetConversation());

        return messages;
    }
}
